import React from 'react';
import { Alert, Card, Col, Row, Spin, Dropdown, Menu } from 'antd';
import { connect } from 'dva';
import moment from 'moment';
import 'moment/locale/zh-cn';
import styles from './homePage.css';
import { Chart, Geom, Axis, Tooltip, Coord, Label, Legend } from 'bizcharts';
import DataSet from '@antv/data-set';
import { Icon } from '@ant-design/compatible';

const reqApi = 'homePage';
const statusMapping = {
  0: { type: 'info', message: '', addMsg: true },
  1: { type: 'warning', message: '提交报名信息' },
  2: { type: 'success', message: '通过审核' },
  3: { type: 'error', message: '审核被拒' },
  4: { type: 'warning', message: '进行交费', addMsg: true },
  5: { type: 'success', message: '经核实确已交费' },
  6: { type: 'success', message: '已被分配班级' },
};
let timer = 0;
const yearData = [];
for (let i = 2021; i <= new Date().getFullYear(); i += 1) {
  yearData.push(i);
}

moment.locale('zh-cn');

export default connect(({ homePage }) => ({ homePage }))((props) => {
  const { dispatch } = props;

  const [loading, loadingSet] = React.useState(false);
  const [cardHeight, cardHeightSet] = React.useState(0); // 卡片高度
  const [year, yearSet] = React.useState(new Date().getFullYear());
  const [data, dataSet] = React.useState({
    numData: [], // 学生总数数据
    listData: [], // 最新动态数据
    barData: [], // 专业报名情况数据
    lineData: [], // 每日报名趋势数据
    countData: [], // 学生分类数据
  });

  // 设置卡片高度
  const funcSetCardHeight = () => {
    const n = window.isPad ? 3 : 2;
    const h = window.isPad ? 334 : 248;
    cardHeightSet(Math.round((window.innerHeight - h) / n));
  };

  // 获取数据
  const funcGetData = () => {
    loadingSet(true);
    dispatch({
      type: reqApi + '/data',
      payload: {year},
    }).then(() => {
      loadingSet(false);
      const { data } = props[reqApi];
      if (data) {
        funcRenderData(data);
      }
      if (timer) {
        clearTimeout(timer);
      }
      timer = setTimeout(funcGetData, 1000 * 120);
    });
  };

  // 渲染数据
  const funcRenderData = data => {
    // 渲染学生总数
    const { countStatus1, countStatus2, countStatus3 } = data;
    const numData = [
      { x: '已报名', y: countStatus1 },
      { x: '已审核', y: countStatus2 },
      { x: '已缴费', y: countStatus3 },
    ];

    // 渲染最新动态
    const { latestData } = data;
    const listData = latestData.map((item, index) => {
      const { addTime, name, nickName, weixinId, phone, remark, status } = item;
      const { type, message, addMsg } = statusMapping[status];
      const userName = (name || (nickName === '微信用户' ? '' : nickName) || phone) || ('学生' + weixinId.substr(weixinId.length - 4));
      let msg = userName + ' 在' + moment(addTime).fromNow();
      msg += ' ' + message + (addMsg ? remark : '');
      return {
        key: index,
        type,
        message: msg,
      };
    });

    // 渲染每日报名趋势数据
    const { trendData } = data;
    let lineData = [];
    for (let key in trendData[0]) {
      const x = parseInt(key.substr(8, 2)) + '日';
      const y = trendData[0][key] - 0;
      lineData.unshift({ x, y });
    }
    const mappingDay = ['今天', '昨天', '前天'];
    lineData = lineData.map((item, index) => {
      const { x, y } = item;
      return {
        x: mappingDay[index] || x,
        y,
      };
    });

    // 渲染专业报名情况
    const { specialData } = data;
    const barData = specialData
      .filter(item => item.num0 > 0 || item.num1 > 0)
      .sort((a, b) => (a.num0 - 0 + (a.num1 - 0)) - (b.num0 - 0 + (b.num1 - 0)))
      .map(item => {
        const { name, num0, num1 } = item;
        return {
          x: name.substr(0, 7),
          男: num1 - 0,
          女: num0 - 0,
        };
      });

    // 渲染学生分类占比
    const { lodging1sex1, lodging1sex0, lodging0sex1, lodging0sex0 } = data.counts;
    const sum = lodging1sex1 + lodging1sex0 + lodging0sex1 + lodging0sex0;
    const countData = [
      { x: '住校男生', y: lodging1sex1, percent: Math.round(lodging1sex1 / sum * 100) },
      { x: '住校女生', y: lodging1sex0, percent: Math.round(lodging1sex0 / sum * 100) },
      { x: '跑堂男生', y: lodging0sex1, percent: Math.round(lodging0sex1 / sum * 100) },
      { x: '跑堂女生', y: lodging0sex0, percent: Math.round(lodging0sex0 / sum * 100) },
    ];

    dataSet({ numData, listData, barData, lineData, countData });
  };

  React.useState(() => {
    if (timer) {
      clearTimeout(timer);
    }

    funcSetCardHeight();
    window.onresize = funcSetCardHeight;
  });

  React.useEffect(() => {
    // componentWillUnmount
    return () => {
      window.onresize = null;
      if (timer) {
        clearTimeout(timer);
      }
    };
  }, []);

  React.useEffect(funcGetData, [year]);

  const { barData, lineData, countData, numData, listData } = data;

  const ds = new DataSet();
  const barDv = ds.createView().source(barData);
  barDv.transform({
    type: 'fold',
    fields: ['男', '女'],
    key: "key",
    value: "value",
  });

  const cols = {
    percent: {
      formatter: value => {
        return value + '%';
      }
    }
  };

  return (
    <Spin spinning={loading} size='large'>
      <Row gutter={[{ md: 24, sm: 16, xs: 8 }, { md: 24, sm: 16, xs: 8 }]}>
        <Col lg={8} md={12} xs={24}>
          <Card
            title='学生总数'
            size='small'
            bordered={false}
            extra={(
              <Dropdown
                overlay={(
                  <Menu
                    selectedKeys={[year + '']}
                    onClick={({key}) => yearSet(key - 0)}
                  >
                    {yearData.map(item =>
                      <Menu.Item key={item}>{item}年</Menu.Item>
                    )}
                  </Menu>
                )}
              >
                <a>{year}年 <Icon type="down" /></a>
              </Dropdown>
            )}
          >
            <div className={styles.cardBody}>
              <Chart
                height={cardHeight}
                data={numData}
                forceFit
                padding={[26, 'auto', 'auto', 'auto']}
              >
                <Axis name='x' />
                <Axis name='y' min={0} />
                <Tooltip showTitle={false} />
                <Geom position='x*y' color='x'>
                  <Label content='y' />
                </Geom>
              </Chart>
            </div>
          </Card>
        </Col>

        <Col lg={16} md={12} xs={24}>
          <Card title='专业报名情况' size='small' bordered={false}>
            <div className={styles.cardBody}>
              <Chart
                height={cardHeight}
                data={barDv}
                forceFit
                padding={['auto', 16, 'auto', 'auto']}
              >
                <Coord transpose />
                <Axis name="x" />
                <Axis name="value" />
                <Tooltip />
                <Geom
                  type="intervalStack"
                  position="x*value"
                  color={['key', ['#178fff', '#f04864']]}
                />
              </Chart>
            </div>
          </Card>
        </Col>

        <Col lg={8} md={12} xs={24}>
          <Card title='最新动态' size='small' bordered={false}>
            <div className={styles.cardBody} style={{ overflow: 'auto' }}>
              {listData.map((item) => {
                const { type, message, key } = item;
                return <Alert banner type={type} message={message} key={key} />;
              })}
            </div>
          </Card>
        </Col>

        <Col lg={8} md={12} xs={24}>
          <Card title='学生分类占比' size='small' bordered={false}>
            <div className={styles.cardBody}>
              <Chart
                height={cardHeight}
                data={countData}
                scale={cols}
                forceFit
                padding='auto'
              >
                <Coord type="theta" />
                <Legend position="right" />
                <Tooltip showTitle={false} />
                <Geom
                  type="intervalStack"
                  position="percent"
                  style={{ lineWidth: 1, stroke: "white" }}
                  color={['x', ['#0088fe', '#ee3b61', '#4ea54d', '#ffbb28']]}
                  tooltip={[
                    "x*y*percent",
                    (x, y, percent) => {
                      return {
                        name: x,
                        value: y + '人（' + percent + '%）',
                      };
                    }
                  ]}
                >
                  <Label
                    content="percent"
                    offset={-40}
                    textStyle={{
                      textAlign: "center",
                      shadowBlur: 2,
                      shadowColor: "rgba(0, 0, 0, 0.5)"
                    }}
                  />
                </Geom>
              </Chart>
            </div>
          </Card>
        </Col>

        <Col lg={8} md={24} xs={24}>
          <Card title='每日报名趋势' size='small' bordered={false}>
            <div className={styles.cardBody}>
              <Chart
                height={cardHeight}
                data={lineData}
                forceFit
                padding='auto'
              >
                <Axis name='x' />
                <Axis name='y' min={0} />
                <Tooltip crosshairs={{ type: 'y' }} />
                <Geom
                  type='line'
                  position='x*y'
                  size={2}
                  tooltip={['x*y', (x, y) => {
                    return {
                      name: '报名人数',
                      title: x,
                      value: y,
                    }
                  }]}
                />
                <Geom
                  type='point'
                  position='x*y'
                  size={4}
                  shape='circle'
                  style={{ stroke: 'white', lineWidth: 1 }}
                  tooltip={['x*y', (x, y) => {
                    return {
                      name: '报名人数',
                      title: x,
                      value: y,
                    }
                  }]}
                />
              </Chart>
            </div>
          </Card>
        </Col>
      </Row>
    </Spin>
  );
});
